﻿#region Using
// System
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

// Csla
using Csla;
#endregion // Using

namespace GACAssemblyExporter.Library
{
    /// <summary>
    /// List of assembly infos
    /// </summary>
    [Serializable()]
    public class AssemblyInfoList: ReadOnlyListBase<AssemblyInfoList, AssemblyInfo>
    {
        #region Constructors
        /**********************************************************************
         * Constructors
         *********************************************************************/
        private AssemblyInfoList() { }
        #endregion // Constructors

        #region Data Portal Methods
        /**********************************************************************
         * Data Portal Methods
         *********************************************************************/
        /// <summary>
        /// Data portal fetch method
        /// </summary>
        /// <param name="criteria"></param>
        private void DataPortal_Fetch(RootDirectoryCriteria criteria)
        {
            if (Directory.Exists(criteria.RootDirectory))
            {
                this.IsReadOnly = false;
                foreach (string gacDir in Directory.GetDirectories(criteria.RootDirectory, "GAC*"))
                {
                    foreach (string assemblyDir in Directory.GetDirectories(gacDir))
                    {
                        this.AddAssemblyInfo(AssemblyInfo.Get(assemblyDir));
                    }// for each assembly dir
                }// for each "GAC" directory
                this.IsReadOnly = true;
            }// if the root directory exists
        }// of DataPortal_Fetch(Criteria)
        #endregion // Data Portal Methods

        #region Modifier Methods
        /**********************************************************************
         * Modifier Methods
         *********************************************************************/
        /// <summary>
        /// Adds an assembly info item
        /// </summary>
        /// <param name="assemblyInfo"></param>
        /// <returns></returns>
        private bool AddAssemblyInfo(AssemblyInfo assemblyInfo)
        {
            bool toReturn = false;

            IEnumerable<AssemblyInfo> existing = from ai in this
                                                 where string.Compare(ai.Name, assemblyInfo.Name, true) == 0
                                                 select ai;

            if (existing.Count<AssemblyInfo>() > 0)
            {
                AssemblyInfo aiExisting = existing.FirstOrDefault<AssemblyInfo>();
                if (aiExisting != null)
                {
                    foreach(VersionInfo vi in assemblyInfo.VersionList)
                    {
                        aiExisting.VersionList.AddVersionInfo(vi);
                    }// for each version
                }// if the value is set
                else
                {
                    this.Add(assemblyInfo);
                    toReturn = true;
                }// if the value isn't set
            }// if this does already exist
            else
            {
                this.Add(assemblyInfo);
                toReturn = true;
            }// if this doesn't already exist

            return toReturn;
        }// of bool AddAssemblyInfo(AssemblyInfo)
        #endregion // Modifier Methods

        #region Factory Methods
        /**********************************************************************
         * Factory Methods
         *********************************************************************/
        /// <summary>
        /// Gets the list of assemblies in a root directory
        /// </summary>
        /// <param name="rootAssemblyDirectory"></param>
        /// <returns></returns>
        public static AssemblyInfoList Get(string rootAssemblyDirectory)
        {
            return DataPortal.Fetch<AssemblyInfoList>(new RootDirectoryCriteria() { RootDirectory = rootAssemblyDirectory });
        }// of Get(string)
        #endregion // Factory Methods
    }// of class AssemblyInfoList
}// of namespace GACAssemblyExporter.Library